package com.ruoyi.common.utils

import com.ruoyi.common.constant.HttpStatus
import com.ruoyi.common.exception.ServiceException
import com.ruoyi.framework.security.LoginUser
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder

/**
 * 安全服务工具类
 *
 * @author ruoyi
 */
object SecurityUtils {
    /**
     * 用户ID
     */
    fun getUserId(): Long? {
        return try {
            getLoginUser().getUserId()
        } catch (e: Exception) {
            throw ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED)
        }
    }

    /**
     * 获取部门ID
     */
    fun getDeptId(): Long? {
        return try {
            getLoginUser().getDeptId()
        } catch (e: Exception) {
            throw ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED)
        }
    }

    /**
     * 获取用户账户
     */
    fun getUsername(): String? {
        return try {
            getLoginUser().username
        } catch (e: Exception) {
            throw ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED)
        }
    }

    /**
     * 获取用户
     */
    fun getLoginUser(): LoginUser {
        return try {
            getAuthentication()!!.principal as LoginUser
        } catch (e: Exception) {
            throw ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED)
        }
    }

    /**
     * 获取Authentication
     */
    fun getAuthentication(): Authentication? {
        return SecurityContextHolder.getContext().authentication
    }

    /**
     * 生成BCryptPasswordEncoder密码
     *
     * @param password 密码
     * @return 加密字符串
     */
    fun encryptPassword(password: String?): String? {
        val passwordEncoder = BCryptPasswordEncoder()
        return passwordEncoder.encode(password)
    }

    /**
     * 判断密码是否相同
     *
     * @param rawPassword     真实密码
     * @param encodedPassword 加密后字符
     * @return 结果
     */
    fun matchesPassword(rawPassword: String?, encodedPassword: String?): Boolean {
        val passwordEncoder = BCryptPasswordEncoder()
        return passwordEncoder.matches(rawPassword, encodedPassword)
    }

    /**
     * 是否为管理员
     *
     * @param userId 用户ID
     * @return 结果
     */
    fun isAdmin(userId: Long?): Boolean {
        return userId != null && 1L == userId
    }
}
